"""
邮件工具模块
提供邮件发送功能
"""
import smtplib
import logging
from email.mime.text import MimeText
from email.mime.multipart import MimeMultipart
from typing import List, Optional, Dict, Any

from flask import current_app, url_for, render_template

logger = logging.getLogger('stehub.app')

def send_email(to_email: str, subject: str, body: str, 
               html_body: Optional[str] = None,
               from_email: Optional[str] = None) -> bool:
    """
    发送邮件
    
    Args:
        to_email: 收件人邮箱
        subject: 邮件主题
        body: 纯文本正文
        html_body: HTML正文（可选）
        from_email: 发件人邮箱
        
    Returns:
        bool: 是否发送成功
    """
    # 获取邮件配置
    smtp_config = current_app.config.get('SMTP', {})
    
    if not smtp_config.get('enabled', False):
        logger.warning("邮件功能未启用")
        return False
    
    try:
        # 创建邮件
        msg = MimeMultipart('alternative')
        msg['Subject'] = subject
        msg['From'] = from_email or smtp_config.get('from_email', 'noreply@stehub.com')
        msg['To'] = to_email
        
        # 添加纯文本版本
        text_part = MimeText(body, 'plain', 'utf-8')
        msg.attach(text_part)
        
        # 添加HTML版本（如果提供）
        if html_body:
            html_part = MimeText(html_body, 'html', 'utf-8')
            msg.attach(html_part)
        
        # 发送邮件
        with smtplib.SMTP(smtp_config['host'], smtp_config.get('port', 587)) as server:
            if smtp_config.get('use_tls', True):
                server.starttls()
            
            if smtp_config.get('username') and smtp_config.get('password'):
                server.login(smtp_config['username'], smtp_config['password'])
            
            server.send_message(msg)
        
        logger.info(f"邮件发送成功: {to_email} - {subject}")
        return True
    
    except Exception as e:
        logger.error(f"邮件发送失败: {str(e)}")
        return False

def send_welcome_email(user_email: str, username: str) -> bool:
    """
    发送欢迎邮件
    
    Args:
        user_email: 用户邮箱
        username: 用户名
        
    Returns:
        bool: 是否发送成功
    """
    subject = "欢迎加入 SteHub 学生交流平台！"
    
    # 从模板渲染邮件内容
    context = {
        'username': username,
        'login_url': url_for('auth.login', _external=True),
        'site_url': url_for('main.index', _external=True),
        'current_year': current_app.config.get('CURRENT_YEAR', 2024)
    }
    
    try:
        # 渲染纯文本版本
        body = render_template('email/welcome.txt', **context)
        
        # 渲染HTML版本
        html_body = render_template('email/welcome.html', **context)
        
        return send_email(user_email, subject, body, html_body)
    
    except Exception as e:
        logger.error(f"欢迎邮件模板渲染失败: {str(e)}")
        # 降级到简单文本
        body = f"""
亲爱的 {username}，

欢迎加入 SteHub 学生交流平台！

我们很高兴您成为我们社区的一员。在 SteHub，您可以：

• 与同学交流学习经验
• 分享学习资源和笔记
• 参与论坛讨论
• 加入实时聊天室

开始探索吧！
{url_for('main.index', _external=True)}

如果您有任何问题，请随时联系我们。

祝学习愉快！
SteHub 团队
"""
        return send_email(user_email, subject, body)

def send_password_reset_email(user_email: str, username: str, 
                            reset_token: str) -> bool:
    """
    发送密码重置邮件
    
    Args:
        user_email: 用户邮箱
        username: 用户名
        reset_token: 重置令牌
        
    Returns:
        bool: 是否发送成功
    """
    reset_url = url_for('auth.reset_password', token=reset_token, _external=True)
    subject = "SteHub - 重置您的密码"
    
    # 从模板渲染邮件内容
    context = {
        'username': username,
        'reset_url': reset_url,
        'current_year': current_app.config.get('CURRENT_YEAR', 2024)
    }
    
    try:
        # 渲染纯文本版本
        body = render_template('email/password_reset.txt', **context)
        
        # 渲染HTML版本
        html_body = render_template('email/password_reset.html', **context)
        
        return send_email(user_email, subject, body, html_body)
    
    except Exception as e:
        logger.error(f"密码重置邮件模板渲染失败: {str(e)}")
        # 降级到简单文本
        body = f"""
亲爱的 {username}，

我们收到了重置您账户密码的请求。

请点击以下链接重置您的密码：
{reset_url}

如果您没有请求重置密码，请忽略此邮件。

此链接将在1小时后过期。

祝好，
SteHub 团队
"""
        return send_email(user_email, subject, body)

def send_notification_email(user_email: str, username: str,
                          notification_type: str, 
                          data: Dict[str, Any]) -> bool:
    """
    发送通知邮件
    
    Args:
        user_email: 用户邮箱
        username: 用户名
        notification_type: 通知类型
        data: 通知数据
        
    Returns:
        bool: 是否发送成功
    """
    # 根据通知类型定制邮件内容
    templates = {
        'new_reply': {
            'subject': '您在 SteHub 的帖子有了新回复',
            'template': 'email/new_reply'
        },
        'new_message': {
            'subject': '您在 SteHub 收到了新消息',
            'template': 'email/new_message'
        },
        'post_liked': {
            'subject': '您在 SteHub 的帖子被点赞',
            'template': 'email/post_liked'
        },
        'mentioned': {
            'subject': '您在 SteHub 被提及',
            'template': 'email/mentioned'
        }
    }
    
    template_info = templates.get(notification_type)
    if not template_info:
        logger.warning(f"未知的通知类型: {notification_type}")
        return False
    
    subject = template_info['subject']
    template_base = template_info['template']
    
    # 从模板渲染邮件内容
    context = {
        'username': username,
        'notification_type': notification_type,
        'data': data,
        'site_url': url_for('main.index', _external=True),
        'current_year': current_app.config.get('CURRENT_YEAR', 2024)
    }
    
    try:
        # 渲染纯文本版本
        body = render_template(f'{template_base}.txt', **context)
        
        # 渲染HTML版本
        html_body = render_template(f'{template_base}.html', **context)
        
        return send_email(user_email, subject, body, html_body)
    
    except Exception as e:
        logger.error(f"通知邮件模板渲染失败: {str(e)}")
        # 降级到简单文本
        body = f"""
亲爱的 {username}，

您在 SteHub 有新的通知。

通知类型: {notification_type}
相关数据: {data}

请登录 SteHub 查看详情：
{url_for('main.index', _external=True)}

祝好，
SteHub 团队
"""
        return send_email(user_email, subject, body)

def validate_email_format(email: str) -> bool:
    """
    验证邮箱格式
    
    Args:
        email: 邮箱地址
        
    Returns:
        bool: 格式是否有效
    """
    import re
    
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return re.match(pattern, email) is not None

def send_bulk_emails(emails: List[str], subject: str, 
                    body: str, html_body: Optional[str] = None) -> Dict[str, Any]:
    """
    批量发送邮件
    
    Args:
        emails: 邮箱列表
        subject: 邮件主题
        body: 纯文本正文
        html_body: HTML正文
        
    Returns:
        dict: 发送结果统计
    """
    results = {
        'total': len(emails),
        'success': 0,
        'failed': 0,
        'failed_emails': []
    }
    
    for email in emails:
        if send_email(email, subject, body, html_body):
            results['success'] += 1
        else:
            results['failed'] += 1
            results['failed_emails'].append(email)
    
    logger.info(f"批量邮件发送完成: 成功 {results['success']}, 失败 {results['failed']}")
    return results

def render_email_template(template_name: str, context: Dict[str, Any]) -> str:
    """
    渲染邮件模板
    
    Args:
        template_name: 模板名称
        context: 模板上下文
        
    Returns:
        str: 渲染后的HTML
    """
    try:
        # 使用Flask的模板系统渲染
        return render_template(template_name, **context)
    except Exception as e:
        logger.error(f"邮件模板渲染失败: {str(e)}")
        # 返回简单的错误信息
        return f"""
        <div style="font-family: Arial, sans-serif; padding: 20px;">
            <h2>SteHub 通知</h2>
            <p>邮件内容渲染失败，请登录网站查看详情。</p>
            <p><a href="{url_for('main.index', _external=True)}">访问 SteHub</a></p>
        </div>
        """

def send_verification_email(user_email: str, username: str, 
                          verification_token: str) -> bool:
    """
    发送邮箱验证邮件
    
    Args:
        user_email: 用户邮箱
        username: 用户名
        verification_token: 验证令牌
        
    Returns:
        bool: 是否发送成功
    """
    verification_url = url_for('auth.verify_email', token=verification_token, _external=True)
    subject = "SteHub - 验证您的邮箱地址"
    
    context = {
        'username': username,
        'verification_url': verification_url,
        'current_year': current_app.config.get('CURRENT_YEAR', 2024)
    }
    
    try:
        body = render_template('email/email_verification.txt', **context)
        html_body = render_template('email/email_verification.html', **context)
        return send_email(user_email, subject, body, html_body)
    
    except Exception as e:
        logger.error(f"邮箱验证邮件模板渲染失败: {str(e)}")
        body = f"""
亲爱的 {username}，

请验证您的 SteHub 邮箱地址。

请点击以下链接完成验证：
{verification_url}

如果您没有创建 SteHub 账户，请忽略此邮件。

祝好，
SteHub 团队
"""
        return send_email(user_email, subject, body)

def send_admin_notification(subject: str, message: str, 
                          level: str = 'info') -> bool:
    """
    发送管理员通知邮件
    
    Args:
        subject: 邮件主题
        message: 通知消息
        level: 通知级别 (info, warning, error)
        
    Returns:
        bool: 是否发送成功
    """
    admin_email = current_app.config.get('ADMIN_EMAIL')
    if not admin_email:
        logger.warning("管理员邮箱未配置")
        return False
    
    context = {
        'subject': subject,
        'message': message,
        'level': level,
        'current_year': current_app.config.get('CURRENT_YEAR', 2024)
    }
    
    try:
        body = render_template('email/admin_notification.txt', **context)
        html_body = render_template('email/admin_notification.html', **context)
        return send_email(admin_email, subject, body, html_body)
    
    except Exception as e:
        logger.error(f"管理员通知邮件模板渲染失败: {str(e)}")
        return send_email(admin_email, subject, message)